﻿using AntMovement.Core.IParameter;
using AntMovement.Core.Tool;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AntMovement.Core.Mvvm
{
    public abstract class ValueChangeBase : INotifyPropertyChanged
    {
        #region 私有变量
        protected ILog _log;
        protected string _path = System.IO.Path.Combine(Environment.CurrentDirectory, "init", "holdparameter");
        #endregion
        public ValueChangeBase(ILog log)
        {
            _log = log;
        }
        #region Synchronize
        private volatile int _lock = 0;

        protected void Locked()
        {
            int lockNumber = 0;
            while (Interlocked.Exchange(ref _lock, 1) != 0)
            {
                _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0; _ = 0;
                if (++lockNumber > 50)
                {
                    Thread.Sleep(1);
                    lockNumber = 0;
                }
            }
        }

        protected void UnLock() => Interlocked.Exchange(ref _lock, 0);
        #endregion
        [System.Text.Json.Serialization.JsonIgnore]
        public bool IsChange { get; set; }
        public event PropertyChangedEventHandler? PropertyChanged;

        protected virtual bool SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null)
        {
            if (SetValue(ref member, value))
            {
                return false;
            }
            OnPropertyChanged(propertyName);
            return true;
        }

        protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        protected virtual bool SetValue<T>(ref T member, T value)
        {
            if (EqualityComparer<T>.Default.Equals(member, value))
            {
                return true;
            }
            member = value;
            Locked();
            IsChange = true;
            UnLock();
            return false;
        }
    }
}
